<?php

use App\Http\Controllers\Api\BaseController;
use App\Models\Meta\WxCircleMetaNum;
use App\Models\Meta\WxCircleMetaStr;
use App\Models\Meta\WxCommentMetaNum;
use App\Models\Meta\WxCommentMetaStr;
use App\Models\Meta\WxPostMetaNum;
use App\Models\Meta\WxPostMetaStr;
use App\Models\Meta\WxShopGoodMetaNum;
use App\Models\Meta\WxShopGoodMetaStr;
use App\Models\Meta\WxTagMetaNum;
use App\Models\Meta\WxTagMetaStr;
use App\Models\Meta\WxUserMetaNum;
use App\Models\Meta\WxUserMetaStr;
use App\Models\Shop\WxShopMetaNum;
use App\Models\Shop\WxShopMetaStr;
use App\Models\Meta\WxUsedMetaNum;
use App\Models\Meta\WxUsedMetaStr;
use App\Models\User\WxUser;
use App\Models\Meta\WxObjectMetaNum;
use App\Models\Meta\WxObjectMetaStr;
use App\Models\WxStrMetaNum;
use App\Models\WxStrMetaStr;
use App\Wen\Utils\ApiUtils;
use App\Wen\Utils\Settings;
use App\Wen\Utils\UserUtils;
use Dcat\Admin\Admin;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\RateLimiter;

require __DIR__.'/../app/Admin/helpers.php';

function _empty_($v, $zero_not_empty = false, $not_trim = false){
    if($v === true){
        return false;
    }
    if(!$not_trim && is_string($v)){
        $v = trim($v);
    }
    if('[object Null]' === $v || $v === 'undefined' || $v === 'null' || $v === 'false'){
        return true;
    }

    if($zero_not_empty){
        if($v === 0 || $v === '0'){
            return false;
        }
    }
    if(is_array($v) && count($v) === 1 && isset($v[0]) && _empty_($v[0], $zero_not_empty) ){
        return true;
    }
    if(empty($v)){
        return true;
    }
    return false;
}


function _empty_default_($value, $default = null){
    if(_empty_($value, true)){
        return $default;
    }
    return $value;
}



function get_mini_domain(){
    return str_replace(['https://', 'http://'], '', env('APP_URL', ''));
}

function _version_compare($version1, $version2){
    if($version1 === 'all'){
        return '<';
    }else if($version2 === 'all'){
        return '>';
    }
    $version1 = ltrim($version1, 'v');
    $version2 = ltrim($version2, 'v');
    $arr1 = explode('.', $version1);
    if(count($arr1) == 3){
        $arr1[] = 0;
    }
    $arr2 = explode('.', $version2);
    if(count($arr2) == 3){
        $arr2[] = 0;
    }
    for ($i = 0; $i < 4; $i++){
        if($arr1[$i] > $arr2[$i]){
            return '>';
        }else if($arr1[$i] == $arr2[$i]){
            continue;
        }else{
            return '<';
        }
    }
    return '=';
}

// 1：查询
// 11：白名单查询
// 2：设置为 examine
// 3: 取消设置 examine
function is_mini_examine_mode($flag = 1){
    global $__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_PLATFORM__,$__MINI_GLOBAL_MODE__,$__MINI_GLOBAL_CURRENT_USER_ID__,$__MINI_GLOBAL_FRONT_VERSION__;
    if($flag == 1 || $flag == 11){
        if(_empty_($__MINI_GLOBAL_MODE__)){
            if($__MINI_GLOBAL_DEVICE__ == 'mp'){
                if(Settings::get('is_examine_mode', 0) == 1 && in_array(_version_compare($__MINI_GLOBAL_FRONT_VERSION__, env('MINI_EXAMINE_VER', 'all')), ['>', '='])){
                    $__MINI_GLOBAL_MODE__ = 'examine';
                    if($flag == 11 && UserUtils::user_permissions_check_by_config($__MINI_GLOBAL_CURRENT_USER_ID__, 'app_examine_mode_white_list')){
                        // 在白名单里
                        $__MINI_GLOBAL_MODE__ = 'normal';
                    }
                }else{
                    $__MINI_GLOBAL_MODE__ = 'normal';
                }
            }else if($__MINI_GLOBAL_DEVICE__ == 'h5'){
                if(Settings::get('is_h5_examine_mode', 0) == 1 && in_array(_version_compare($__MINI_GLOBAL_FRONT_VERSION__, env('H5_EXAMINE_VER', 'all')), ['>', '='])){
                    $__MINI_GLOBAL_MODE__ = 'examine';
                    if($flag == 11 && UserUtils::user_permissions_check_by_config($__MINI_GLOBAL_CURRENT_USER_ID__, 'app_h5_examine_mode_white_list')){
                        // 在白名单里
                        $__MINI_GLOBAL_MODE__ = 'normal';
                    }
                }else{
                    $__MINI_GLOBAL_MODE__ = 'normal';
                }
            }else if($__MINI_GLOBAL_DEVICE__ == 'app'){
                if($__MINI_GLOBAL_PLATFORM__ == 'ios'){
                    if(Settings::get('is_app_ios_examine_mode', 0) == 1 && in_array(_version_compare($__MINI_GLOBAL_FRONT_VERSION__, env('IOS_EXAMINE_VER', 'all')), ['>', '='])){
                        $__MINI_GLOBAL_MODE__ = 'examine';
                        if($flag == 11 && UserUtils::user_permissions_check_by_config($__MINI_GLOBAL_CURRENT_USER_ID__, 'app_app_ios_examine_mode_white_list')){
                            // 在白名单里
                            $__MINI_GLOBAL_MODE__ = 'normal';
                        }
                    }else{
                        $__MINI_GLOBAL_MODE__ = 'normal';
                    }
                }else if($__MINI_GLOBAL_PLATFORM__ == 'android'){
                    if(Settings::get('is_app_android_examine_mode', 0) == 1 && in_array(_version_compare($__MINI_GLOBAL_FRONT_VERSION__, env('ANDROID_EXAMINE_VER', 'all')), ['>', '='])){
                        $__MINI_GLOBAL_MODE__ = 'examine';
                        if($flag == 11 && UserUtils::user_permissions_check_by_config($__MINI_GLOBAL_CURRENT_USER_ID__, 'app_app_android_examine_mode_white_list')){
                            // 在白名单里
                            $__MINI_GLOBAL_MODE__ = 'normal';
                        }
                    }else{
                        $__MINI_GLOBAL_MODE__ = 'normal';
                    }
                }
            }
        }
        if($__MINI_GLOBAL_MODE__ == 'examine'){
            return true;
        }
        return false;
    }else if($flag == 2){
        if($__MINI_GLOBAL_DEVICE__ == 'mp'){
            Settings::set('is_examine_mode', 1, true);
        }else if($__MINI_GLOBAL_DEVICE__ == 'h5'){
            Settings::set('is_h5_examine_mode', 1, true);
        }else if($__MINI_GLOBAL_DEVICE__ == 'app'){
            if($__MINI_GLOBAL_PLATFORM__ == 'ios'){
                Settings::set('is_app_ios_examine_mode', 1, true);
            }else if($__MINI_GLOBAL_PLATFORM__ == 'android'){
                Settings::set('is_app_android_examine_mode', 1, true);
            }
        }
    }else if($flag == 3){
        if($__MINI_GLOBAL_DEVICE__ == 'mp'){
            Settings::set('is_examine_mode', 0, true);
        }else if($__MINI_GLOBAL_DEVICE__ == 'h5'){
            Settings::set('is_h5_examine_mode', 0, true);
        }else if($__MINI_GLOBAL_DEVICE__ == 'app'){
            if($__MINI_GLOBAL_PLATFORM__ == 'ios'){
                Settings::set('is_app_ios_examine_mode', 0, true);
            }else if($__MINI_GLOBAL_PLATFORM__ == 'android'){
                Settings::set('is_app_android_examine_mode', 0, true);
            }
        }
    }
}

// 0:修改 1：新增或修改
function _update_env($data, $deles = [], $flag = 0){
    $envPath = base_path() . DIRECTORY_SEPARATOR . '.env';
    $contentArray = collect(file($envPath, FILE_IGNORE_NEW_LINES));
    foreach ($contentArray as $key=>$value) {
        if(!_empty_($value)){
            $cont = explode('=', $value);
            if ($deles && in_array($cont[0], $deles)) {
                $contentArray[$key] = '';
            }else{
                if (array_key_exists($cont[0], $data)) {
                    $contentArray[$key] = $cont[0].'='.trim_all_space($data[$cont[0]]);
                    unset($data[$cont[0]]);
                } else {
                    $contentArray[$key] =  _array_key($cont, 0, '').'='.trim_all_space(_array_key($cont, 1, ''));
                }
            }
        }
    }

    $arr = $contentArray->toArray();

    if($flag == 1 && count($data) > 0){
        $arr[] = '';
        foreach ($data as $key => $item){
            $arr[] = $key.'='.$item;
        }
    }

    $last_line_empty = false;
    $new_arr =[];
    foreach ($arr as $line){
        if(!_empty_($line)){
            $last_line_empty = false;
            $new_arr[] = $line;
        }else{
            if($last_line_empty){
                continue;
            }else{
                $last_line_empty = true;
                $new_arr[] = $line;
            }
        }
    }
    $content = implode("\n", $new_arr);
    file_put_contents($envPath, $content);
}



function _ip_address($ip){
    if($ip){
        $res = ApiUtils::ali_request(\App\Wen\Utils\Settings::get('app_ali_ip_address_appcode', ''), 'https://ips.market.alicloudapi.com/iplocaltion', ['ip'=>$ip]);
        if($res){
            if($res['code'] == 100 && $res['result']){
                return [
                    'longitude' => $res['result']['lng'], //经度
                    'latitude' => $res['result']['lat'], //纬度
                    'adcode' => $res['result']['adcode'],//归属地编码
                    'country' => $res['result']['nation'], //归属国家
                    'en_short' => $res['result']['en_short'], //英文简称
                    'en_name' => $res['result']['en_name'], //归属国家英文名称
                    'province' => $res['result']['province'], //归属省份
                    'city' => $res['result']['city'], //归属城市
                    'district' => $res['result']['district'], //归属县区
                ];
            }else{
                UserUtils::assistant_notice('admin', json_encode($res, JSON_UNESCAPED_UNICODE).'_002');
                return null;
            }
        }
        _logger_(__file__, __line__, '[全局配置-api配置-ip属地]解析请求返回为空，你检查下是不是没有购买套餐'.$ip);
        return null;
    }
}



function _limit_user($action, $uid, $times, $tip = ''){

    $executed = RateLimiter::attempt(
        'online:'.$action.':'.$uid,
        $times,
        function() {

        }
    );

    if (! $executed) {
        if(UserUtils::is_mini_admin($uid)){

        }else{
            if(Cache::has('limit:user:cache:'.$uid)){

            }else{
                if(_empty_($tip)){
                    $tip = '攻击平台有可能被系统拉入黑名单，请勿点击过于频繁';
                }
//                    GatewayUtils::error_message(GatewayUtils::uid2client_id($uid), '攻击平台有可能被系统拉入黑名单');
                UserUtils::assistant_notice($uid, $tip);
                $limit_times = Cache::get('limit:user:times:'.$uid, 0);
                if($limit_times > 0){
                    Cache::forget('limit:user:times:'.$uid);
                }
                $limit_times += 1;
                if($limit_times > 3){
                    $the_user = WxUser::find($uid);
                    UserUtils::add_user_notice(1003, $uid, '管理员已封禁您的账号7天', '您的账号存在异常行为['.$tip.']，如有异议，请联系客服。', 100);
                    UserUtils::lock_user_incre($the_user, 2, 3600 * 24 * 7, $tip.'[多次]');
                }else{
                    Cache::put('limit:user:times:'.$uid, $limit_times, 7200);
                }
                Cache::put('limit:user:cache:'.$uid, 1, 30);
            }

            $baseController = new BaseController();
            return $baseController->fail(200010, [], '您慢一点，小的跟不上你');
        }
    }
}

function _logger_($file, $line, $data, $type = 'error'){

    if(is_array($data)){
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
    }
    if($file){
        $arr_tmp = explode('/', $file);
        $file = end($arr_tmp);
    }
    try {
        $data = "\n=======================".$file.':'.$line. "=======================\n" . $data."\n----------------------------------------------------------------\n";
        if($type == 'info'){
            Log::info($data);
        }else if($type == 'warning'){
            Log::warning($data);
        }else if($type == 'alert'){
            Log::alert($data);
        }else if($type == 'debug'){
            Log::debug($data);
        }else{
            Log::error($data);
        }

        if(is_string($data)){
            if(strpos($data, 'Column not found:') !== false){
                Cache::forget('__MINISNS_VERSION__');
            }
        }

    }catch (\Exception $e){
//        exec( 'chmod -R ugo+rw '.storage_path(''));
    }

}



function _between_($num , $min, $max){
    if(_empty_($num)){
        return 0;
    }
    if($num > $max){
        $num = $max;
    }else if($num < $min){
        $num = $min;
    }
    return $num;
}

function _abs($num){
    if(is_string($num)){
        if(strpos($num, '.') === false){
            return abs((int)$num);
        }else{
            return abs((float)$num);
        }
    }
    return abs($num);
}

function mini_rand($min, $max){
    if($min > $max){
        $tmp = $max;
        $max = $min;
        $min = $tmp;
    }
    global $__MINI_GLOBAL_RAND_CACHE__;
    if($max - $min <= 2){
        if($max - $min == 1){
            if($__MINI_GLOBAL_RAND_CACHE__ == -1){
                if(mt_rand(0, 1) == 0){
                    $__MINI_GLOBAL_RAND_CACHE__ = $min;
                    return $min;
                }else{
                    $__MINI_GLOBAL_RAND_CACHE__ = $max;
                    return $max;
                }
            }else if($min == $__MINI_GLOBAL_RAND_CACHE__){
                $__MINI_GLOBAL_RAND_CACHE__ = $max;
                return $max;
            }else{
                $__MINI_GLOBAL_RAND_CACHE__ = $min;
                return $min;
            }
        }else if($max - $min == 2){
            if($min == $__MINI_GLOBAL_RAND_CACHE__){
                $num = mt_rand($min + 1, $max);
                $__MINI_GLOBAL_RAND_CACHE__ = $num;
                return $num;
            }else if($min + 1 == $__MINI_GLOBAL_RAND_CACHE__){
                $rand = mt_rand(0, 1);
                if($rand == 0){
                    $__MINI_GLOBAL_RAND_CACHE__ = $min;
                    return $min;
                }else{
                    $__MINI_GLOBAL_RAND_CACHE__ = $max;
                    return $max;
                }
            }else{
                $num = mt_rand($min, $max - 1);
                $__MINI_GLOBAL_RAND_CACHE__ = $num;
                return $num;
            }
        }
    }else if($max - $min <= 100){
        $num = mt_rand($min, $max);
        if($num == $__MINI_GLOBAL_RAND_CACHE__){
            if($num + 1 <= $max){
                $num = $num + 1;
            }else if($num - 1 >= $min){
                $num = $num - 1;
            }
            $__MINI_GLOBAL_RAND_CACHE__ = $num;
            return $num;
        }
    }
    $num = mt_rand($min, $max);
    $flag = 10;
    while ($num == $__MINI_GLOBAL_RAND_CACHE__ && $flag--){
        $num = mt_rand($min, $max);
    }
    $__MINI_GLOBAL_RAND_CACHE__ = $num;
    return $num;
}


function get_os(){
    // override the detection of the operation system
    // by checking for an env var and returning early
    if (isset($_ENV['PHANTOMJS_PLATFORM'])) {
        return strtolower($_ENV['PHANTOMJS_PLATFORM']);
    }

    if (isset($_SERVER['PHANTOMJS_PLATFORM'])) {
        return strtolower($_SERVER['PHANTOMJS_PLATFORM']);
    }

    $uname = strtolower(php_uname());

    if (strpos($uname, 'darwin') !== false ||
        strpos($uname, 'openbsd') !== false ||
        strpos($uname, 'freebsd') !== false
    ) {
        return 'macosx';
    } elseif (strpos($uname, 'win') !== false) {
        return 'windows';
    } elseif (strpos($uname, 'linux') !== false) {
        return 'linux';
    } else {
        return 'unknown';
    }
}


function _array_rand_element($arr, $num = 1){
    if($arr && is_array($arr)){
        if($num == 1){
            if(count($arr) == 1){
                return $arr[0];
            }
            return $arr[mini_rand(0, count($arr) - 1)];
        }else if($num > 1){
            if(count($arr) <= $num){
                return $arr;
            }
            $keys = array_rand($arr, $num);
            $result = [];
            foreach ($keys as $key){
                $result[$key] = $arr[$key];
            }
            return $result;
        }
    }
    return null;
}



function get_mini_version_code($str = ''){
    if(_empty_($str)){
        global $__MINI_GLOBAL_VERSION__;
        $version_arr = explode(' ', $__MINI_GLOBAL_VERSION__);
    }else{
        $version_arr = explode(' ', $str);
    }
    return (int)$version_arr[0].'.'.(int)$version_arr[1].'.'.(int)$version_arr[2] . ( (int)$version_arr[3] > 0 ? '.'.(int)$version_arr[3] : '' );
}

/**
 * @param int $flag 0: 代表返回模型，1：是否会员 2:setting
 * @return mixed|null
 */
function mini_current_user($flag = 0, $key = ''){
    global $__MINI_GLOBAL_CURRENT_USER__, $__MINI_GLOBAL_CURRENT_USER_ID__;
    if($__MINI_GLOBAL_CURRENT_USER__ === null){
        if($__MINI_GLOBAL_CURRENT_USER_ID__ > 0){
            $__MINI_GLOBAL_CURRENT_USER__ = UserUtils::get_cached_user($__MINI_GLOBAL_CURRENT_USER_ID__);
        }
    }
    if($__MINI_GLOBAL_CURRENT_USER__){

        if($flag === 0){
            return $__MINI_GLOBAL_CURRENT_USER__;
        }else if($flag === 1){
            return $__MINI_GLOBAL_CURRENT_USER__['is_member'];
        }else if($flag === 2){
            if($__MINI_GLOBAL_CURRENT_USER__['setting']){
                return $__MINI_GLOBAL_CURRENT_USER__['setting'][$key];
            }
        }
    }
    return null;
}




function _encodeURIComponent($scene){
    return urlencode(iconv("gbk", "UTF-8", $scene));
}



function _decodeURIComponent($scene){
    return iconv("UTF-8", "gbk",  urldecode($scene));
}



function user_admin_config($key = null, $value = null)
{
    $session = session();

    if (! $config = $session->get('admin.config')) {
        $config = config('admin');

        $config['lang'] = config('app.locale');
    }

    if (is_array($key)) {
        // 保存
        foreach ($key as $k => $v) {
            Arr::set($config, $k, $v);
        }

        $session->put('admin.config', $config);

        return;
    }

    if ($key === null) {
        return $config;
    }

    return Arr::get($config, $key, $value);
}



function _mini_emoji($content, $text = false){
    if(_empty_($content)){
        return '';
    }
    $app_emoji_cache = json_decode(Cache::get('app_emoji_cache', '[]'), true);
    if(_empty_($app_emoji_cache)){
        $page1 = \App\Wen\Utils\Settings::get('app_emoji_page_1', []);
        $page2 = \App\Wen\Utils\Settings::get('app_emoji_page_2', []);
        $page3 = \App\Wen\Utils\Settings::get('app_emoji_page_3', []);
        $app_emoji_cache = [];
        $partern = '';
        $app_emoji_alt_str = '';
        if($page1){
            foreach ($page1 as $emoji){
                $key = _preg_prepare($emoji['alt']);
                $app_emoji_cache[$emoji['alt']] = $emoji;
                $app_emoji_alt_str .= $emoji['alt'];
                if(_empty_($partern)){
                    $partern = '$'.$key.'';
                }else{
                    $partern .= '|'.$key.'';
                }

            }
        }
        if($page2){
            foreach ($page2 as $emoji){
                $key = _preg_prepare($emoji['alt']);
                $app_emoji_cache[$emoji['alt']] = $emoji;
                $app_emoji_alt_str .= $emoji['alt'];
                if(_empty_($partern)){
                    $partern = '$'.$key.'';
                }else{
                    $partern .= '|'.$key.'';
                }
            }
        }
        if($page3){
            foreach ($page3 as $emoji){
                $key = _preg_prepare($emoji['alt']);
                $app_emoji_cache[$emoji['alt']] = $emoji;
                $app_emoji_alt_str .= $emoji['alt'];
                if(_empty_($partern)){
                    $partern = '$'.$key.'';
                }else{
                    $partern .= '|'.$key.'';
                }
            }
        }
        if($partern){
            $partern .= '$';
        }
        $app_emoji_cache['partern'] = $partern;
        Cache::put('app_emoji_cache', json_encode($app_emoji_cache));
        Cache::put('app_emoji_alt_str', $app_emoji_alt_str);
    }
    if($app_emoji_cache){
        if($text){
            return preg_replace_callback('$<mini-emoji alt="([^"]*?)" [^>]*?></mini-emoji>$', function ($v){
                return $v[1];
            }, $content);
        }else{
            $partern = $app_emoji_cache['partern'];
            if($partern){
                return preg_replace_callback($partern, function ($v) use ($app_emoji_cache){
                    return '<mini-emoji alt="'.$app_emoji_cache[$v[0]]['alt'].'" emoji="'.$app_emoji_cache[$v[0]]['emoji'].'" width="'.$app_emoji_cache[$v[0]]['width'].'" height="'.$app_emoji_cache[$v[0]]['height'].'"></mini-emoji>';
                }, $content);
            }
        }
    }
    return $content;
}

function warp2br($content){
    if(_empty_($content)){
        return '';
    }
    return str_replace(["\n", "\r\n", "&amp;", '\r\n'], '<br>', $content);
}

function _mini_phone($content, $reback = false){
    if($reback){
        return preg_replace_callback('$<mini-contact type="([^"]*?)" text="([^"]*?)"></mini-contact>$', function ($r){
            return $r[2];
        }, $content);
    }else{
        return preg_replace_callback('$(?<![0-9])(1[3456789]\d{9})(?![0-9])$', function ($r){
            return str_replace($r[1], '<mini-contact type="tel" text="'.$r[1].'"></mini-contact>', $r[0]);
        }, $content);
    }
}

function _mini_aite($aiter_uid , $content, $aite_scene = 1, $placed = true, $post_id = 0, $comment_id = 0){
    $user_arr = [];
    if($placed){
        preg_match_all('$<mini-aite uid="([^"]*?)" name="([^"]*?)"></mini-aite>$', $content, $matchs);

        if($matchs && $matchs[1]){
            $user_arr = array_unique($matchs[1]);
        }
    }else{
        preg_replace_callback('/@([\p{P}\\x{4e00}-\\x{9fa5}a-zA-Z0-9°C\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}]{2,30})/us', function ($v) use (&$user_arr){
            $name=strip_tags($v[1]);
            $user = WxUser::where('user_name', $name)->first();
            if($user){
                $user_arr[] = $user->id;
                if($user){
                    return '<mini-aite uid="'.$user->id.'" name="'.$user->user_name.'"></mini-aite>';
                }else{
                    return $v[0];
                }
            }else{
                _logger_(__file__, __line__, $name);
                return $v[0];
            }
        }, $content);
        $user_arr = array_unique($user_arr);
    }
    if($user_arr){
        $filter_users = [$aiter_uid];
        $aiter_user_name = UserUtils::get_cached_user_name($aiter_uid);
        foreach ($user_arr as $at_user_id){
            if(in_array($at_user_id, $filter_users)){
                continue;
            }else{
                if(true){
                    if($aite_scene == 1){
                        if($post_id > 0){
                            UserUtils::add_user_notice(4009, $at_user_id, '@了你', '「<a href="/pages/user/user?id='.$aiter_uid.'">'.$aiter_user_name.'</a>」在笔记中艾特了你', 102, $post_id);
                        }else{
                            UserUtils::add_user_notice(4009, $at_user_id, '@了你', '「<a href="/pages/user/user?id='.$aiter_uid.'">'.$aiter_user_name.'</a>」在笔记中艾特了你', 102);
                        }
                    }else if($aite_scene == 2){
                        if($post_id > 0) {
                            UserUtils::add_user_notice(4010, $at_user_id, '@了你', '「<a href="/pages/user/user?id='.$aiter_uid.'">'.$aiter_user_name.'</a>」在评论中艾特了你', 102, $post_id);
                        }else{
                            UserUtils::add_user_notice(4010, $at_user_id, '@了你', '「<a href="/pages/user/user?id='.$aiter_uid.'">'.$aiter_user_name.'</a>」评论中艾特了你', 102);
                        }
                    }
                }
            }
        }
    }
}

function _mini_aite_replace($content, $reback = false){
    if(_empty_($content)){
        return '';
    }

    if($reback){
        return preg_replace_callback('$<mini-aite uid="([^"]*?)" name="([^"]*?)"></mini-aite>$', function ($v){
            $name=strip_tags($v[2]);
            return '@'.$name.' ';
        }, $content);
    }else{
        $user_arr = [];
        return preg_replace_callback('/@([\p{P}\\x{4e00}-\\x{9fa5}a-zA-Z0-9°C\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}]{2,30})/us', function ($v) use (&$user_arr){
            $name=strip_tags($v[1]);
            $user = WxUser::where('user_name', $name)->first();
            if($user){
                $user_arr[] = $user->id;
                if($user){
                    return '<mini-aite uid="'.$user->id.'" name="'.$user->user_name.'"></mini-aite>';
                }else{
                    return $v[0];
                }
            }else{
                return $v[0];
            }
        }, $content);
    }

}

function _preg_prepare($content){
    if(_empty_($content)){
        return '';
    }
    return preg_replace_callback('$[\[\]\{\}\.\?\^\+]$', function ($v){
        return '\\'.$v[0];
    }, $content);
}

function current_time( $type = 'mysql', $gmt = 0 ) {

    if ( 'mysql' === $type ) {
        $format = 'Y-m-d H:i:s';
    }else if('day' === $type){
        $format = 'Y-m-d';
    }

    $timezone = $gmt ? new DateTimeZone( 'UTC' ) : null;
    $datetime = new DateTime( 'now', $timezone );

    return $datetime->format( $format );
}

function timetostr($timestamp, $format = 'Y-m-d H:i:s'){
    return date($format, $timestamp);
}

/**
 * 时间日期格式化为多少天前
 * @param sting|intval $date_time
 * @param intval $type 1、'Y-m-d H:i:s' 2、时间戳
 * @return string
 */

function format_datetime($date_time,$type=1,$format=''){
    if($type == 1){
        $timestamp = strtotime($date_time);
    }elseif($type == 2){
        $timestamp = $date_time;
    }
    if(!_empty_($format)){
        return date($format,$timestamp);
    }
    $etime = time() - $timestamp;
    if ($etime < 10){
        return '刚刚';
    }else if( $etime > 259200 && $etime < 864000){
        return date('m-d H:i', $timestamp);
    }else if($etime > 864000){
        return date('Y-m-d', $timestamp);
    }else{
        $interval = array (
            12 * 30 * 24 * 60 * 60  =>  '年前',
            30 * 24 * 60 * 60       =>  '个月前',
            7 * 24 * 60 * 60        =>  '星期前',
            24 * 60 * 60            =>  '天前',
            60 * 60                 =>  '小时前',
            60                      =>  '分钟前',
            1                       =>  '秒前'
        );
        foreach ($interval as $secs => $str) {
            if (0 !=$c=floor($etime/(int)$secs)) {
                return $c.$str;
            }
        }
    }
}



function __system_is_model_enable($author, $name){
    return file_exists(app_path('Extensions/'.$author.'/'.$name.'/composer.json')) && Admin::extension()->enabled($author.'.'.$name);
}


function unicode_encode($name)
{
    $name = iconv('UTF-8', 'UCS-2', $name);
    $len = strlen($name);
    $str = '';
    for ($i = 0; $i < $len - 1; $i = $i + 2)
    {
        $c = $name[$i];
        $c2 = $name[$i + 1];
        if (ord($c) > 0)
        {   //两个字节的文字
            $str .= '\u'.base_convert(ord($c), 10, 16).str_pad(base_convert(ord($c2), 10, 16), 2, 0, STR_PAD_LEFT);
        }
        else
        {
            $str .= $c2;
        }
    }
    return $str;
}


function _get_origin_attribute($table, $options , $attribute){
    return DB::table($table)->where($options)->value($attribute);
}


function unicode_decode($name)
{
    //转换编码，将Unicode编码转换成可以浏览的utf-8编码
    $pattern = '/([\w]+)|(\\\u([\w]{4}))/i';
    preg_match_all($pattern, $name, $matches);
    if (!empty($matches))
    {
        $name = '';
        for ($j = 0; $j < count($matches[0]); $j++)
        {
            $str = $matches[0][$j];
            if (strpos($str, '\\u') === 0)
            {
                $code = base_convert(substr($str, 2, 2), 16, 10);
                $code2 = base_convert(substr($str, 4), 16, 10);
                $c = chr($code).chr($code2);
                $c = iconv('UCS-2', 'UTF-8', $c);
                $name .= $c;
            }
            else
            {
                $name .= $str;
            }
        }
    }
    return $name;
}


function _array_key($data, $key, $default){
    if($data){
        if(isset($data[$key])){
            return _empty_($data[$key], true) ? $default : $data[$key];
        }
    }
    return $default;
}


function get_user_meta($user_id, $meta_key, $type = 's'){
    if(_empty_($user_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxUserMetaStr::where([ ['user_id', '=',  $user_id], ['meta_key', '=',  $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxUserMetaNum::where([ ['user_id', '=', $user_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxUserMetaStr::where([ ['user_id', '=', $user_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}


function update_user_meta($user_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($user_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxUserMetaStr::where( [ ['user_id', '=',  $user_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxUserMetaStr::updateOrCreate(
            ['user_id' => $user_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxUserMetaNum::where( [ ['user_id', '=',  $user_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxUserMetaNum::updateOrCreate(
            ['user_id' => $user_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxUserMetaStr::where( [ ['user_id', '=',  $user_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxUserMetaStr::updateOrCreate(
            ['user_id' => $user_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}

function trim_all_space($str, $keep_distance = false, $keep_wrap = false){
    if($keep_distance){
        if($keep_wrap){
            $oldchar=array("　　","\t","\r","&nbsp;&nbsp;");
        }else{
            $oldchar=array("
","　　","\t","\n","\r","&nbsp;&nbsp;", '<br>');
        }
        $newchar=" ";
    }else{
        if($keep_wrap){
            $oldchar=array("　"," ","\t","\r","&nbsp;");
        }else{
            $oldchar=array("
","　"," ","\t","\n","\r","&nbsp;", '<br>');
        }
        $newchar = '';
    }

    return trim(str_replace($oldchar,$newchar,$str));
}

function get_post_meta($post_id, $meta_key, $type = 's'){
    if(_empty_($post_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxPostMetaStr::where([ ['post_id', '=', $post_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxPostMetaNum::where([ ['post_id', '=', $post_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxPostMetaStr::where([ ['post_id', '=', $post_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_post_meta($post_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($post_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxPostMetaStr::where( [ ['post_id', '=',  $post_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxPostMetaStr::updateOrCreate(
            ['post_id' => $post_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxPostMetaNum::where( [ ['post_id', '=',  $post_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxPostMetaNum::updateOrCreate(
            ['post_id' => $post_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxPostMetaStr::where( [ ['post_id', '=',  $post_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxPostMetaStr::updateOrCreate(
            ['post_id' => $post_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}


function get_comment_meta($comment_id, $meta_key, $type = 's'){
    if(_empty_($comment_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxCommentMetaStr::where([ ['comment_id', '=', $comment_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){

        return WxCommentMetaNum::where([ ['comment_id', '=', $comment_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){

        $meta_value = WxCommentMetaStr::where([ ['comment_id', '=', $comment_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}


function update_comment_meta($comment_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($comment_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxCommentMetaStr::where( [ ['comment_id', '=',  $comment_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxCommentMetaStr::updateOrCreate(
            ['comment_id' => $comment_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxCommentMetaNum::where( [ ['comment_id', '=',  $comment_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxCommentMetaNum::updateOrCreate(
            ['comment_id' => $comment_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxCommentMetaStr::where( [ ['comment_id', '=',  $comment_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxCommentMetaStr::updateOrCreate(
            ['comment_id' => $comment_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}


function get_circle_meta($circle_id, $meta_key, $type = 's'){
    if(_empty_($circle_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxCircleMetaStr::where([ ['circle_id', '=', $circle_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){

        return WxCircleMetaNum::where([ ['circle_id', '=', $circle_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxCircleMetaStr::where([ ['circle_id', '=', $circle_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_circle_meta($circle_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($circle_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxCircleMetaStr::where( [ ['circle_id', '=',  $circle_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxCircleMetaStr::updateOrCreate(
            ['circle_id' => $circle_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxCircleMetaNum::where( [ ['circle_id', '=',  $circle_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxCircleMetaNum::updateOrCreate(
            ['circle_id' => $circle_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxCircleMetaStr::where( [ ['circle_id', '=',  $circle_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxCircleMetaStr::updateOrCreate(
            ['circle_id' => $circle_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}

function get_tag_meta($tag_id, $meta_key, $type = 's'){
    if(_empty_($tag_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxTagMetaStr::where([ ['tag_id', '=', $tag_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxTagMetaNum::where([ ['tag_id', '=', $tag_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxTagMetaStr::where([ ['tag_id', '=', $tag_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_tag_meta($tag_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($tag_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxTagMetaStr::where( [ ['tag_id', '=',  $tag_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxTagMetaStr::updateOrCreate(
            ['tag_id' => $tag_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxTagMetaNum::where( [ ['tag_id', '=',  $tag_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxTagMetaNum::updateOrCreate(
            ['tag_id' => $tag_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxTagMetaStr::where( [ ['tag_id', '=',  $tag_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxTagMetaStr::updateOrCreate(
            ['tag_id' => $tag_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}


function get_shop_meta($shop_id, $meta_key, $type = 's'){
    if(_empty_($shop_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxShopMetaStr::where([ ['shop_id', '=', $shop_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxShopMetaNum::where([ ['shop_id', '=', $shop_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxShopMetaStr::where([ ['shop_id', '=', $shop_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_shop_meta($shop_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($shop_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxShopMetaStr::where( [ ['shop_id', '=',  $shop_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxShopMetaStr::updateOrCreate(
            ['shop_id' => $shop_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxShopMetaNum::where( [ ['shop_id', '=',  $shop_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxShopMetaNum::updateOrCreate(
            ['shop_id' => $shop_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxShopMetaStr::where( [ ['tag_id', '=',  $shop_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxShopMetaStr::updateOrCreate(
            ['shop_id' => $shop_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}


function get_good_meta($good_id, $meta_key, $type = 's'){
    if(_empty_($good_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxShopGoodMetaStr::where([ ['good_id', '=', $good_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxShopGoodMetaNum::where([ ['good_id', '=', $good_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxShopGoodMetaStr::where([ ['good_id', '=', $good_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_good_meta($good_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($good_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxShopGoodMetaStr::where( [ ['good_id', '=',  $good_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxShopGoodMetaStr::updateOrCreate(
            ['good_id' => $good_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxShopGoodMetaNum::where( [ ['good_id', '=',  $good_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxShopGoodMetaNum::updateOrCreate(
            ['good_id' => $good_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxShopGoodMetaStr::where( [ ['good_id', '=',  $good_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxShopGoodMetaStr::updateOrCreate(
            ['good_id' => $good_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}


function get_object_meta($object_type, $object_id, $meta_key, $type = 's'){
    if(_empty_($object_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxObjectMetaStr::where([ ['object_type', '=', $object_type], ['object_id', '=', $object_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxObjectMetaNum::where([ ['object_type', '=', $object_type], ['object_id', '=', $object_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxObjectMetaStr::where([ ['object_type', '=', $object_type], ['object_id', '=', $object_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function get_used_meta($used_id, $meta_key, $type = 's'){
    if(_empty_($used_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxusedMetaStr::where([ ['used_id', '=', $used_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxusedMetaNum::where([ ['used_id', '=', $used_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxusedMetaStr::where([ ['used_id', '=', $used_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_used_meta($used_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($used_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxusedMetaStr::where( [ ['used_id', '=',  $used_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxusedMetaStr::updateOrCreate(
            ['used_id' => $used_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxusedMetaNum::where( [ ['used_id', '=',  $used_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxusedMetaNum::updateOrCreate(
            ['used_id' => $used_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxusedMetaStr::where( [ ['used_id', '=',  $used_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxusedMetaStr::updateOrCreate(
            ['used_id' => $used_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}

/**
 * @param $object_type 1: 公众号推文 2：俱乐部
 * @param $object_id
 * @param $meta_key
 * @param $meta_value
 * @param string $type
 * @return false
 */
function update_object_meta($object_type, $object_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($object_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxObjectMetaStr::where( [ ['object_type', '=', $object_type], ['object_id', '=',  $object_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxObjectMetaStr::updateOrCreate(
            ['object_type' => $object_type, 'object_id' => $object_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxObjectMetaNum::where( [ ['object_type', '=', $object_type], ['object_id', '=',  $object_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxObjectMetaNum::updateOrCreate(
            ['object_type' => $object_type, 'object_id' => $object_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxObjectMetaStr::where( [ ['object_type', '=', $object_type], ['object_id', '=',  $object_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxObjectMetaStr::updateOrCreate(
            ['object_type' => $object_type, 'object_id' => $object_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}


function get_shop_order_meta($order_id, $meta_key, $type = 's'){
    if(_empty_($order_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxStrMetaStr::where([ ['meta_name', '=', 'shop:order:'.$order_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxStrMetaNum::where([ ['meta_name', '=', 'shop:order:'.$order_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxStrMetaStr::where([ ['meta_name', '=', 'shop:order:'.$order_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_shop_order_meta($shop_order_id, $meta_key, $meta_value, $type = 's'){

    if(_empty_($shop_order_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxStrMetaStr::where( [ ['meta_name', '=',  'shop:order:'.$shop_order_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaStr::updateOrCreate(
            ['meta_name' => 'shop:order:'.$shop_order_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxStrMetaNum::where( [ ['meta_name', '=',  'shop:order:'.$shop_order_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaNum::updateOrCreate(
            ['meta_name' => 'shop:order:'.$shop_order_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxStrMetaStr::where( [ ['meta_name', '=',  'shop:order:'.$shop_order_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaStr::updateOrCreate(
            ['meta_name' => 'shop:order:'.$shop_order_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;

}

function get_order_meta($order_id, $meta_key, $type = 's'){
    if(_empty_($order_id) || _empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxStrMetaStr::where([ ['meta_name', '=', 'order:'.$order_id], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxStrMetaNum::where([ ['meta_name', '=', 'order:'.$order_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxStrMetaStr::where([ ['meta_name', '=', 'order:'.$order_id], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_order_meta($order_id, $meta_key, $meta_value, $type = 's'){
    if(_empty_($order_id) || _empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxStrMetaStr::where( [ ['meta_name', '=',  'order:'.$order_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaStr::updateOrCreate(
            ['meta_name' => 'order:'.$order_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxStrMetaNum::where( [ ['meta_name', '=',  'order:'.$order_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaNum::updateOrCreate(
            ['meta_name' => 'order:'.$order_id, 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxStrMetaStr::where( [ ['meta_name', '=',  'order:'.$order_id], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaStr::updateOrCreate(
            ['meta_name' => 'order:'.$order_id, 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}

function get_site_meta($meta_key, $type = 's'){
    if(_empty_($meta_key)){
        return null;
    }

    if($type == 's'){
        return WxStrMetaStr::where([ ['meta_name', '=', '__site__'], ['meta_key', '=', $meta_key] ])->value('meta_value') ?? '';
    }else if($type == 'n'){
        return WxStrMetaNum::where([ ['meta_name', '=', '__site__'], ['meta_key', '=', $meta_key] ])->value('meta_value');
    }else if($type == 'j'){
        $meta_value = WxStrMetaStr::where([ ['meta_name', '=', '__site__'], ['meta_key', '=', $meta_key] ])->value('meta_value');
        return $meta_value ? json_decode($meta_value, true) : [];
    }
    return null;
}

function update_site_meta($meta_key, $meta_value, $type = 's'){
    if(_empty_($meta_key, true)){
        return false;
    }

    if($type == 's'){
        if(_empty_($meta_value, true)){
            return WxStrMetaStr::where( [ ['meta_name', '=',  '__site__'], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaStr::updateOrCreate(
            ['meta_name' => '__site__', 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'n'){
        if(_empty_($meta_value, true)){
            return WxStrMetaNum::where( [ ['meta_name', '=',  '__site__'], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaNum::updateOrCreate(
            ['meta_name' => '__site__', 'meta_key' => $meta_key],
            ['meta_value' => $meta_value]
        );
    }else if($type == 'j'){
        if(_empty_($meta_value)){
            return WxStrMetaStr::where( [ ['meta_name', '=',  '__site__'], ['meta_key', '=',  $meta_key] ] )->delete();
        }
        return WxStrMetaStr::updateOrCreate(
            ['meta_name' => '__site__', 'meta_key' => $meta_key],
            ['meta_value' => json_encode($meta_value ?: '')]
        );
    }
    return false;
}


function get_tmp_meta($type, $obj_id, $meta_key){
    return \App\Models\Meta\WxTmpMetum::where('type_obj_id', $type.'_'.$obj_id)->where('meta_key', $meta_key)->value('meta_value');
}

function update_tmp_meta($type, $obj_id, $meta_key, $meta_value){
    if(_empty_($meta_value, true)){
        return \App\Models\Meta\WxTmpMetum::where('type_obj_id', $type.'_'.$obj_id)->where('meta_key', $meta_key)->delete();
    }
    return \App\Models\Meta\WxTmpMetum::updateOrCreate(['type_obj_id'=>$type.'_'.$obj_id, 'meta_key'=>$meta_key],['meta_value'=>$meta_value]);
}

/**
 * 不检验用户是否存在
 * 1:笔记 2:圈子 3:商品 4:用户 5:话题
 */

function update_user_visit($uid, $type, $object_id){
    if($uid && $type && $object_id){
        \App\Jobs\UpdateUserVisitJob::dispatch($uid, $type, $object_id, true);
    }
}

function _multi_key($key){
    global $__MINI_GLOBAL_TENANT_ID__;
    if($__MINI_GLOBAL_TENANT_ID__ > 0){
        return $key.'__'.$__MINI_GLOBAL_TENANT_ID__;
    }
    return $key;
}

function tenant_config($key, $default = '', $tenant_id = -1){
    global $__MINI_GLOBAL_TENANT_ID__;
    if($tenant_id == -1){
        $tenant_id = $__MINI_GLOBAL_TENANT_ID__;
    }

    if($tenant_id > 0){
        if($key == 'admin.logo'){
            return '<img src="'.Settings::get('tenant_admin_logo', 'https://mini.minisns.cn/statics/minisns.svg').'" width="80%" style="max-width: unset;max-height: unset;">';
        }else if($key == 'admin.name'){
            return Settings::get('tenant_admin_name', 'MiniSNS');
        }else if($key == 'admin.login.user'){
            return Settings::get('tenant_admin_admin_name', '');
        }else if($key == 'admin.login.password'){
            return Settings::get('tenant_admin_admin_password', '');
        }else if($key == 'admin.login.bg'){
            return Settings::get('tenant_site_admin_login_bg', 'https://img.mini.minisns.cn/back/back.jpg');
        }
    }else{
        if($key == 'admin.logo'){
            return '<img src="'.Settings::get('main_site_admin_logo', 'https://mini.minisns.cn/statics/minisns.svg').'" width="80%" style="max-width: unset;max-height: unset;">';
        }else if($key == 'admin.name'){
            return Settings::get('main_site_admin_name', 'MiniSNS');
        }else if($key == 'admin.login.user'){
            return Settings::get('main_site_admin_admin_name', '');
        }else if($key == 'admin.login.password'){
            return Settings::get('main_site_admin_admin_password', '');
        }else if($key == 'admin.login.bg'){
            return Settings::get('main_site_admin_login_bg', 'https://img.mini.minisns.cn/back/back.jpg');
        }
        return config($key, $default);
    }
}


function is_object_user_special($uid, $object_tenant_id, $only_super = false){
    global $__MINI_GLOBAL_IS_ADMIN_SUPER__, $__MINI_GLOBAL_TENANT_ID__;
    if($__MINI_GLOBAL_IS_ADMIN_SUPER__){
        // 主站超级管理员-管所有
        return true;
    }else if($__MINI_GLOBAL_TENANT_ID__ > 0 && UserUtils::is_mini_supder_admin($uid) && $__MINI_GLOBAL_TENANT_ID__ == $object_tenant_id){
        // 分站超级管理员-管对应的分站
        return true;
    }else if(!$only_super && UserUtils::is_mini_admin($uid, true) && $__MINI_GLOBAL_TENANT_ID__ == $object_tenant_id){
        // 普通管理员-管对应的分站
        return true;
    }
    return false;
}